﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Yedda;
using System.Web;
using System.Net;
using System.IO;
using System.Diagnostics;


namespace Astrila.QckTwit
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        const string userTextFormat = @"User: {0}";
        const string reminderTimerTextFormat = @"Reminder: {0} mins";
        const string row2TextFormat = @"Ctrl+Enter to send.    Status: {1}    Chars:{0}    .";

        Twitter twitter = new Twitter();
        Hotkey hk = new Hotkey();


        int randomRed, randomGreen, randomBlue;
        private void MainForm_Load(object sender, EventArgs e)
        {
            UpdateTimerValue();
            UpdateUserLabel();
            UpdateRow2Label("Not sent");

            hk.KeyCode = Keys.T;
            hk.Alt = true;
            hk.Shift = true;
            hk.Pressed += new HandledEventHandler(HotKey_Pressed);
            if (hk.GetCanRegister(this))
                hk.Register(this);
            else
                MessageBox.Show("Hotkey registration failed because other application has Alt+Shift+T.");

            Random rnd = new Random();
            randomRed = rnd.Next(160, 266);
            randomGreen = rnd.Next(180, 256);
            randomBlue = rnd.Next(180, 256);
        }

        private void UpdateTimerValue()
        {
            string timerValueAsString = GetTimerValueAsString();

            linkSetTimer.Text = string.Format(reminderTimerTextFormat, timerValueAsString);
            linkSetTimer.LinkArea = new LinkArea(reminderTimerTextFormat.IndexOf("{0}"), timerValueAsString.Length);

            if (Properties.Settings.Default.ReminderTimer > 0)
            {
                timerReminder.Interval = Properties.Settings.Default.ReminderTimer * 60000;
                timerReminder.Enabled = true;
            }
            else
            {
                timerReminder.Enabled = false;
            }

        }

        private static string GetTimerValueAsString()
        {
            string timerValueAsString;
            if (Properties.Settings.Default.ReminderTimer > 0)
            {
                timerValueAsString = Properties.Settings.Default.ReminderTimer.ToString();
            }
            else
            {
                timerValueAsString = "Not Set";
            }
            return timerValueAsString;
        }

        void HotKey_Pressed(object sender, HandledEventArgs e)
        {
            ActivateMainForm(true);
        }


        private bool IsValidUserName()
        {
            return (Properties.Settings.Default.UserName ?? string.Empty).Trim().Length > 0;
        }

        private string GetUserNameForDisplay()
        {
            if (!IsValidUserName())
                return "Click to enter login info";
            else
                return Properties.Settings.Default.UserName;
        }

        private string GetTimerForDisplay()
        {
            if (!IsValidUserName())
                return "Click to enter login info";
            else
                return Properties.Settings.Default.UserName;
        }


        private int UpdateRow2Label(string sendStatus)
        {
            int totalChars = TotalChars();

            row2Label.Text = string.Format(row2TextFormat, 140 - totalChars, sendStatus);

            return totalChars;
        }

        private void twitTextBox_TextChanged(object sender, EventArgs e)
        {
            int totalChars = UpdateRow2Label("Not sent");

            if (totalChars > CharCountForFirstAndLastBlocks)
            {
                int totalTwits = GetTwitCount(totalChars);
                twitTextBox.SelectionBackColor = Color.FromArgb(
                    randomRed - ((totalTwits * randomGreen) % 30),
                    randomGreen - ((totalTwits * randomBlue) % 30),
                    randomBlue - ((totalTwits * randomRed) % 30)
                    );
            }
        }

        private int TotalChars()
        {
            int totalChars = twitTextBox.Text.Length;
            return totalChars;
        }


        const int CharCountForFirstAndLastBlocks = 140;
        const int CharCountForIntermediateBlocks = 140;
        const int TinyUrlSize = 25;

        private int GetTwitCount(int totalChars)
        {
            if (totalChars <= CharCountForFirstAndLastBlocks)
                return 1;
            else
                return 1 + ((totalChars - CharCountForFirstAndLastBlocks) / CharCountForIntermediateBlocks);
        }

        private List<string> FormatTwitText()
        {
            string fullText = twitTextBox.Text;

            //Break it down to 140 chars blocks
            List<string> textBlockList = new List<string>();
            int lenthRemaining = fullText.Length;
            int nextPointInText = 0;
            do
            {
                int charsInThisBlock;
                if (lenthRemaining > CharCountForFirstAndLastBlocks)
                {
                    charsInThisBlock = (nextPointInText > 0) ? CharCountForIntermediateBlocks : CharCountForFirstAndLastBlocks;
                    textBlockList.Add(((nextPointInText > 0)?"...":"")
                        + fullText.Substring(nextPointInText, charsInThisBlock) + "...");
                }
                else
                {
                    charsInThisBlock = CharCountForFirstAndLastBlocks;
                    textBlockList.Add(((nextPointInText > 0)?"...":"")
                        + fullText.Substring(nextPointInText));
                }
                nextPointInText += charsInThisBlock;
                lenthRemaining -= charsInThisBlock;
            }
            while (lenthRemaining > 0);

            return textBlockList;
        }

        private string GetTinyUrl(string url)
        {
            WebRequest request = WebRequest.Create("http://tinyurl.com/api-create.php?url=" + url);
            using (WebResponse response = request.GetResponse())
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    return reader.ReadToEnd();
                }
            }
        }

        private void mailNotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ActivateMainForm(true);
        }

        private void ActivateMainForm(bool clearContent)
        {
            if (!this.Visible)
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
                this.Activate();
                this.BringToFront();

                if (clearContent)
                {
                    twitTextBox.Text = string.Empty;
                    linkTextBox.Text = string.Empty;
                }

                if (!IsValidUserName())
                {
                    PromptLogin();
                }
            }
        }

        private void PromptLogin()
        {
            using (TwitterLogin loginFom = new TwitterLogin())
            {
                if (loginFom.ShowDialog(this) == DialogResult.OK)
                {
                    Properties.Settings.Default.UserName = loginFom.UserName;
                    Properties.Settings.Default.Password = loginFom.Password;
                    Properties.Settings.Default.Save();

                    UpdateUserLabel();
                    UpdateRow2Label("Login Saved");
                }
            }
        }

        private void UpdateUserLabel()
        {
            userLabel.Text = string.Format(userTextFormat, GetUserNameForDisplay());
            userLabel.LinkArea = new LinkArea(userTextFormat.IndexOf("{0}"), Properties.Settings.Default.UserName.Length);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                this.Hide();
            }
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            this.Hide();
            mailNotifyIcon.ShowBalloonTip(3000, "QckTwit", "Press Shift+Alt+T anytime to update twitter", ToolTipIcon.Info);
        }

        private void mailNotifyIcon_BalloonTipClicked(object sender, EventArgs e)
        {
            ActivateMainForm(false);
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ActivateMainForm(true);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void statusLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            PromptLogin();
        }

        private void insertLinkButton_Click(object sender, EventArgs e)
        {
            twitTextBox.SelectedText = GetTinyUrl(linkTextBox.Text);
        }

        private void linkTextBox_Enter(object sender, EventArgs e)
        {
            linkTextBox.ForeColor = Color.Blue;
            linkTextBox.SelectAll();
            linkTextBox.SelectionLength = linkTextBox.Text.Length;
        }

        private void linkTextBox_Leave(object sender, EventArgs e)
        {
            linkTextBox.SelectionLength = 0;
            linkTextBox.ForeColor = Color.Silver;
        }

        private void linkSetTimer_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string timerValueAsString = GetTimerValueAsString();
            timerValueAsString = Microsoft.VisualBasic.Interaction.InputBox("Remind me every following minutes (0 to remove)", "Set Reminder", timerValueAsString, -1, -1);
            int reminderMinutes;
            if (int.TryParse(timerValueAsString, out reminderMinutes))
            {
                Properties.Settings.Default.ReminderTimer = reminderMinutes;
                Properties.Settings.Default.Save();
            }
            UpdateTimerValue();
        }

        private void timerReminder_Tick(object sender, EventArgs e)
        {
            ActivateMainForm(true);
        }

        private void notifyIconContextMenu_Opening(object sender, CancelEventArgs e)
        {
            toolStripMenuItemPauseReminder.Enabled = timerReminder.Enabled;
            toolStripMenuItemContinueReminder.Enabled = (!timerReminder.Enabled) && (Properties.Settings.Default.ReminderTimer > 0);
        }

        private void toolStripMenuItemSetReminder_Click(object sender, EventArgs e)
        {
            linkSetTimer_LinkClicked(null, null);
        }

        private void toolStripMenuItemPauseReminder_Click(object sender, EventArgs e)
        {
            timerReminder.Stop();
        }

        private void toolStripMenuItemContinueReminder_Click(object sender, EventArgs e)
        {
            timerReminder.Start();
        }

        private void toolStripMenuItemOpenTwitterWebsite_Click(object sender, EventArgs e)
        {
            Process.Start("http://twitter.com");
        }

        private void twitTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.Enter)
            {
                try
                {
                    this.Cursor = Cursors.WaitCursor;
                    UpdateRow2Label("Sending...");

                    this.Hide();
                    mailNotifyIcon.ShowBalloonTip(30000, "QckTwit", "Sending to Twitter...", ToolTipIcon.Info);

                    List<string> textBlocks = FormatTwitText();
                    foreach (string textBlock in textBlocks)
                    {
                        twitter.Update(Properties.Settings.Default.UserName, Properties.Settings.Default.Password, textBlock, Twitter.OutputFormatType.XML);
                    }

                    UpdateRow2Label("Sent");
                    mailNotifyIcon.ShowBalloonTip(3000, "QckTwit", "Twitter is updated!", ToolTipIcon.Info);

                    e.Handled = true;
                }
                catch (Exception ex)
                {
                    ActivateMainForm(false);
                    MessageBox.Show(ex.Message, "Error sending to Twitter", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    this.Cursor = Cursors.Default;
                }
            }
        }


    }
}
